//package com.yu.init.controller;
//
//import cn.hutool.core.io.FileUtil;
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import com.yu.init.annotation.AuthCheck;
//import com.yu.init.common.BaseResponse;
//import com.yu.init.common.DeleteRequest;
//import com.yu.init.common.ErrorCode;
//import com.yu.init.common.ResultUtils;
//import com.yu.init.constant.CommonConstant;
//import com.yu.init.constant.UserConstant;
//import com.yu.init.enums.Enums;
//import com.yu.init.exception.BusinessException;
//import com.yu.init.exception.ThrowUtils;
//import com.yu.init.manager.RedisLimiterManager;
//import com.yu.init.manager.SparkManager;
//import com.yu.init.model.dto.score.*;
//import com.yu.init.model.entity.Score;
//import com.yu.init.model.entity.User;
//import com.yu.init.model.vo.BiResponse;
//import com.yu.init.service.ScoreService;
//import com.yu.init.service.UserService;
//import com.yu.init.utils.ExcelUtils;
//import com.yu.init.utils.SqlUtils;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.ObjectUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.beans.BeanUtils;
//import org.springframework.web.bind.annotation.*;
//import org.springframework.web.multipart.MultipartFile;
//
//import javax.annotation.Resource;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.util.Arrays;
//import java.util.List;
//import java.util.concurrent.CompletableFuture;
//import java.util.concurrent.ThreadPoolExecutor;
//
///**
// * 积分接口
// *
//
// */
//@RestController
//@RequestMapping("/score")
//@Slf4j
//public class ScoreController {
//
//    @Resource
//    private ScoreService scoreService;
//
//    @Resource
//    private UserService userService;
//
//
//    @Resource
//    private RedisLimiterManager redisLimiterManager;
//
//    @Resource
//    private ThreadPoolExecutor threadPoolExecutor;
//
////    @Resource
////    private BiMessageProducer biMessageProducer;
//
//    @Resource
//    private SparkManager sparkManager;
//
//
//    // region 增删改查
//
//    /**
//     * 创建
//     *
//     * @param scoreAddRequest
//     * @param request
//     * @return
//     */
//    @PostMapping("/add")
//    public BaseResponse<Long> addScore(@RequestBody ScoreAddRequest scoreAddRequest, HttpServletRequest request) {
//        if (scoreAddRequest == null) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        Score score = new Score();
//        BeanUtils.copyProperties(scoreAddRequest, score);
//        User loginUser = userService.getLoginUser(request);
//        score.setUserId(loginUser.getId());
//        boolean result = scoreService.save(score);
//        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
//              long newScoreId = score.getId();
//        return ResultUtils.success(newScoreId);
//    }
//
//    /**
//     * 删除
//     *
//     * @param deleteRequest
//     * @param request
//     * @return
//     */
//    @PostMapping("/delete")
//    public BaseResponse<Boolean> deleteScore(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
//        if (deleteRequest == null || deleteRequest.getId() <= 0) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        User user = userService.getLoginUser(request);
//        long id = deleteRequest.getId();
//        // 判断是否存在
//        Score oldScore = scoreService.getById(id);
//        ThrowUtils.throwIf(oldScore == null, ErrorCode.NOT_FOUND_ERROR);
//        // 仅本人或管理员可删除
//        if (!oldScore.getUserId().equals(user.getId()) && !userService.isAdmin(request)) {
//            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
//        }
//        boolean b = scoreService.removeById(id);
//        return ResultUtils.success(b);
//    }
//
//    /**
//     * 更新（仅管理员）
//     *
//     * @param scoreUpdateRequest
//     * @return
//     */
//    @PostMapping("/update")
//    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
//    public BaseResponse<Boolean> updateScore(@RequestBody ScoreUpdateRequest scoreUpdateRequest) {
//        if (scoreUpdateRequest == null || scoreUpdateRequest.getId() <= 0) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        Score score = new Score();
//        BeanUtils.copyProperties(scoreUpdateRequest, score);
//        long id = scoreUpdateRequest.getId();
//        // 判断是否存在
//        Score oldScore = scoreService.getById(id);
//        ThrowUtils.throwIf(oldScore == null, ErrorCode.NOT_FOUND_ERROR);
//        boolean result = scoreService.updateById(score);
//        return ResultUtils.success(result);
//    }
//
//    /**
//     * 根据 id 获取
//     *
//     * @param id
//     * @return
//     */
//    @GetMapping("/get")
//    public BaseResponse<Score> getScoreById(long id, HttpServletRequest request) {
//        if (id <= 0) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        Score score = scoreService.getById(id);
//        if (score == null) {
//            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
//        }
//        return ResultUtils.success(score);
//    }
//
//    /**
//     * 分页获取列表（封装类）
//     *
//     * @param scoreQueryRequest
//     * @param request
//     * @return
//     */
//    @PostMapping("/list/page")
//    public BaseResponse<Page<Score>> listScoreByPage(@RequestBody ScoreQueryRequest scoreQueryRequest,
//            HttpServletRequest request) {
//        long current = scoreQueryRequest.getCurrent();
//        long size = scoreQueryRequest.getPageSize();
//        // 限制爬虫
//        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
//        Page<Score> scorePage = scoreService.page(new Page<>(current, size),
//                getQueryWrapper(scoreQueryRequest));
//        return ResultUtils.success(scorePage);
//    }
//
//    /**
//     * 分页获取当前用户创建的资源列表
//     *
//     * @param scoreQueryRequest
//     * @param request
//     * @return
//     */
//    @PostMapping("/my/list/page")
//    public BaseResponse<Page<Score>> listMyScoreByPage(@RequestBody ScoreQueryRequest scoreQueryRequest,
//            HttpServletRequest request) {
//        if (scoreQueryRequest == null) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        User loginUser = userService.getLoginUser(request);
//        scoreQueryRequest.setUserId(loginUser.getId());
//        long current = scoreQueryRequest.getCurrent();
//        long size = scoreQueryRequest.getPageSize();
//        // 限制爬虫
//        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
//        Page<Score> scorePage = scoreService.page(new Page<>(current, size),
//                getQueryWrapper(scoreQueryRequest));
//        return ResultUtils.success(scorePage);
//    }
//
//    // endregion
//
//    /**
//     * 编辑（用户）
//     *
//     * @param scoreEditRequest
//     * @param request
//     * @return
//     */
//    @PostMapping("/edit")
//    public BaseResponse<Boolean> editScore(@RequestBody ScoreEditRequest scoreEditRequest, HttpServletRequest request) {
//        if (scoreEditRequest == null || scoreEditRequest.getId() <= 0) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        Score score = new Score();
//        BeanUtils.copyProperties(scoreEditRequest, score);
//        User loginUser = userService.getLoginUser(request);
//        long id = scoreEditRequest.getId();
//        // 判断是否存在
//        Score oldScore = scoreService.getById(id);
//        ThrowUtils.throwIf(oldScore == null, ErrorCode.NOT_FOUND_ERROR);
//        // 仅本人或管理员可编辑
//        if (!oldScore.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
//            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
//        }
//        boolean result = scoreService.updateById(score);
//        return ResultUtils.success(result);
//    }
//
//    /**
//     * 智能分析（同步）
//     *
//     * @param multipartFile
//     * @param genScoreByAiRequest
//     * @param request
//     * @return
//     */
//    @PostMapping("/gen")
//    public BaseResponse<BiResponse> genScoreByAi(@RequestPart("file") MultipartFile multipartFile,
//                                                 GenScoreByAiRequest genScoreByAiRequest, HttpServletRequest request){
//        String name = genScoreByAiRequest.getName();
//        String goal = genScoreByAiRequest.getGoal();
//        String scoreType = genScoreByAiRequest.getScoreType();
//        // 校验
//        ThrowUtils.throwIf(StringUtils.isBlank(goal), ErrorCode.PARAMS_ERROR, "目标为空");
//        ThrowUtils.throwIf(StringUtils.isNotBlank(name) && name.length() > 100, ErrorCode.PARAMS_ERROR, "名称过长");
//        // 校验文件
//        long size = multipartFile.getSize();
//        String originalFilename = multipartFile.getOriginalFilename();
//        // 校验文件大小
//        final long ONE_MB = 1024 * 1024L;
//        ThrowUtils.throwIf(size > ONE_MB, ErrorCode.PARAMS_ERROR, "文件超过 1M");
//        // 校验文件后缀 aaa.png
//        String suffix = FileUtil.getSuffix(originalFilename);
//        final List<String> validFileSuffixList = Arrays.asList("xlsx");
//        ThrowUtils.throwIf(!validFileSuffixList.contains(suffix), ErrorCode.PARAMS_ERROR, "文件后缀非法");
//
//        User loginUser = userService.getLoginUser(request);
//        // 限流判断，每个用户一个限流器
//        redisLimiterManager.doRateLimit("genScoreByAi_" + loginUser.getId());
//        // 构造用户输入
//
//        StringBuilder userInput = new StringBuilder();
//
//        userInput.append("你是一个数据分析师和前端开发专家，接下来我会按照以下固定格式给你提供内容:").append("\n");
//        userInput.append("分析需求：").append("\n");
//        // 拼接分析目标
//        String userGoal = goal;
//        if (StringUtils.isNotBlank(scoreType)) {
//            userGoal += "，请使用" + scoreType;
//        }
//        userInput.append(userGoal).append("\n");
//        userInput.append("原始数据：").append("\n");
//        // 压缩后的数据
//        String csvData = ExcelUtils.excelToCsv(multipartFile);
//        userInput.append(csvData).append("\n");
//        userInput.append("请根据这两部分内容，按照以下指定格式生成内容（此外不要输出任何多余的开头、结尾、注释）\n" +
//                "【【【【【\n" +
//                "{前端 Escores V5 的 option 配置对象的json字符串格式的js代码，合理地将数据进行可视化，不要生成任何多余的内容，比如注释}\n" +
//                "【【【【【\n" +
//                "{明确的数据分析结论，越详细越好，不要生成多余的注释\n}" +
//                "最终生成的前端代码和分析结论使用【【【【隔离开;");
//        // 没有按照你的预计生成结论 3.0和3.5的区别？感觉是3.0太蠢了，没有按照模板返回正确的结论
//        String result = sparkManager.sendMesToAIUseXingHuo(userInput.toString());
//        System.out.println(result);
//        String[] split = result.split("【【【【");
//        // TODO 没有考虑向星火ai请求分析结果时可能失败导致result返回结果为null
//        String genScore = split[1];
//        String genResult = split[2];
//
//
//
//        // 插入到数据库
//        Score score = new Score();
//        score.setName(name);
//        score.setGoal(goal);
//        score.setScoreData(csvData);
//        score.setScoreType(scoreType);
//        score.setGenScore(genScore);
//        score.setGenResult(genResult);
//        score.setUserId(loginUser.getId());
//        boolean saveResult = scoreService.save(score);
//        ThrowUtils.throwIf(!saveResult, ErrorCode.SYSTEM_ERROR, "图表保存失败");
//        BiResponse biResponse = new BiResponse();
//        biResponse.setGenScore(genScore);
//        biResponse.setGenResult(genResult);
//        biResponse.setScoreId(score.getId());
//        return ResultUtils.success(biResponse);
//    }
//
//    /**
//     * 智能分析（异步）
//     *
//     * @param multipartFile
//     * @param genScoreByAiRequest
//     * @param request
//     * @return
//     */
//    @PostMapping("/gen/async")
//    public BaseResponse<BiResponse> genScoreByAiAsync(@RequestPart("file") MultipartFile multipartFile,
//                                             GenScoreByAiRequest genScoreByAiRequest, HttpServletRequest request) {
//        String name = genScoreByAiRequest.getName();
//        String goal = genScoreByAiRequest.getGoal();
//        String scoreType = genScoreByAiRequest.getScoreType();
//        // 校验
//        ThrowUtils.throwIf(StringUtils.isBlank(goal), ErrorCode.PARAMS_ERROR, "目标为空");
//        ThrowUtils.throwIf(StringUtils.isNotBlank(name) && name.length() > 100, ErrorCode.PARAMS_ERROR, "名称过长");
//        // 校验文件
//        long size = multipartFile.getSize();
//        String originalFilename = multipartFile.getOriginalFilename();
//        // 校验文件大小
//        final long ONE_MB = 1024 * 1024L;
//        ThrowUtils.throwIf(size > ONE_MB, ErrorCode.PARAMS_ERROR, "文件超过 1M");
//        // 校验文件后缀 aaa.png
//        String suffix = FileUtil.getSuffix(originalFilename);
//        final List<String> validFileSuffixList = Arrays.asList("xlsx", "xls");
//        ThrowUtils.throwIf(!validFileSuffixList.contains(suffix), ErrorCode.PARAMS_ERROR, "文件后缀非法");
//
//        User loginUser = userService.getLoginUser(request);
//        // 限流判断，每个用户一个限流器
//        redisLimiterManager.doRateLimit("genScoreByAi_" + loginUser.getId());
//        long biModelId = 1659171950288818178L;
//        // 构造用户输入
//
//        StringBuilder userInput = new StringBuilder();
//
//        userInput.append("你是一个数据分析师和前端开发专家，接下来我会按照以下固定格式给你提供内容:").append("\n");
//        userInput.append("分析需求：").append("\n");
//        // 拼接分析目标
//        String userGoal = goal;
//        if (StringUtils.isNotBlank(scoreType)) {
//            userGoal += "，请使用" + scoreType;
//        }
//        userInput.append(userGoal).append("\n");
//        userInput.append("原始数据：").append("\n");
//        // 压缩后的数据
//        String csvData = ExcelUtils.excelToCsv(multipartFile);
//        userInput.append(csvData).append("\n");
//        userInput.append("请根据这两部分内容，按照以下指定格式生成内容（此外不要输出任何多余的开头、结尾、注释）\n" +
//                "【【【【【\n" +
//                "{前端 Escores V5 的 option 配置对象的json字符串格式的js代码，合理地将数据进行可视化，不要生成任何多余的内容，比如注释}\n" +
//                "【【【【【\n" +
//                "{明确的数据分析结论，越详细越好，不要生成多余的注释\n}" +
//                "最终生成的前端代码和分析结论使用【【【【隔离开;");
//        // 插入到数据库
//        Score score = new Score();
//        score.setName(name);
//        score.setGoal(goal);
//        score.setScoreData(csvData);
//        score.setScoreType(scoreType);
//        score.setStatus(Enums.WAITING.getMsg());
//        score.setUserId(loginUser.getId());
//        boolean saveResult = scoreService.save(score);
//        ThrowUtils.throwIf(!saveResult, ErrorCode.SYSTEM_ERROR, "图表保存失败");
//
//        // todo 建议处理任务队列满了后，抛异常的情况
//        CompletableFuture.runAsync(() -> {
//            // 先修改图表任务状态为 “执行中”。等执行成功后，修改为 “已完成”、保存执行结果；执行失败后，状态修改为 “失败”，记录任务失败信息。
//            Score updateScore = new Score();
//            updateScore.setId(score.getId());
//            updateScore.setStatus(Enums.RUNNING.getMsg());
//            boolean b = scoreService.updateById(updateScore);
//            if (!b) {
//                handleScoreUpdateError(score.getId(), "更新图表执行中状态失败");
//                return;
//            }
//            // 调用 AI
//            String result = sparkManager.sendMesToAIUseXingHuo(userInput.toString());
//            String[] splits = result.split("【【【【");
//            if (splits.length >3) {
//                handleScoreUpdateError(score.getId(), "AI 生成错误");
//                return;
//            }
//            String genScore = splits[1].trim();
//            String genResult = splits[2].trim();
//            Score updateScoreResult = new Score();
//            updateScoreResult.setId(score.getId());
//            updateScoreResult.setGenScore(genScore);
//            updateScoreResult.setGenResult(genResult);
//            // todo 建议定义状态为枚举值
//            updateScoreResult.setStatus(Enums.WAITING.getMsg());
//            boolean updateResult = scoreService.updateById(updateScoreResult);
//            if (!updateResult) {
//                handleScoreUpdateError(score.getId(), "更新图表成功状态失败");
//            }
//        }, threadPoolExecutor);
//
//        BiResponse biResponse = new BiResponse();
//        biResponse.setScoreId(score.getId());
//        return ResultUtils.success(biResponse);
//    }
//
//    /**
//     * 智能分析（异步消息队列）
//     * @param multipartFile
//     * @param genScoreByAiRequest
//     * @param request
//     * @return
//     */
//
//
//
//    @PostMapping("/gen/async/mq")
//    public BaseResponse<BiResponse> genScoreByAiAsyncMq(@RequestPart("file") MultipartFile multipartFile,
//                                                        GenScoreByAiRequest genScoreByAiRequest, HttpServletRequest request, HttpServletResponse response) {
//
//
//
//
//        String name = genScoreByAiRequest.getName();
//        String goal = genScoreByAiRequest.getGoal();
//        String scoreType = genScoreByAiRequest.getScoreType();
//        // 校验
//        ThrowUtils.throwIf(StringUtils.isBlank(goal), ErrorCode.PARAMS_ERROR, "目标为空");
//        ThrowUtils.throwIf(StringUtils.isNotBlank(name) && name.length() > 100, ErrorCode.PARAMS_ERROR, "名称过长");
//        //文件不能为空
//        ThrowUtils.throwIf(multipartFile.isEmpty(), ErrorCode.PARAMS_ERROR, "文件为空");
//        // 校验文件
//        long size = multipartFile.getSize();
//        String originalFilename = multipartFile.getOriginalFilename();
//        // 校验文件大小
//        final long ONE_MB = 1024 * 1024L;
//        ThrowUtils.throwIf(size > ONE_MB, ErrorCode.PARAMS_ERROR, "文件超过 1M");
//        // 校验文件后缀 aaa.png
//        String suffix = FileUtil.getSuffix(originalFilename);
//        final List<String> validFileSuffixList = Arrays.asList("xlsx", "xls");
//        ThrowUtils.throwIf(!validFileSuffixList.contains(suffix), ErrorCode.PARAMS_ERROR, "文件后缀非法");
//
//        User loginUser = userService.getLoginUser(request);
//        // 限流判断，每个用户一个限流器
//        redisLimiterManager.doRateLimit("genScoreByAi_" + loginUser.getId());
//        long biModelId = 1659171950288818178L;
//        // 构造用户输入
//        StringBuilder userInput = new StringBuilder();
//        userInput.append("分析需求：").append("\n");
//
//        // 拼接分析目标
//        String userGoal = goal;
//        if (StringUtils.isNotBlank(scoreType)) {
//            userGoal += "，请使用" + scoreType;
//        }
//        userInput.append(userGoal).append("\n");
//        userInput.append("原始数据：").append("\n");
//        // 压缩后的数据
//        String csvData = ExcelUtils.excelToCsv(multipartFile);
//        userInput.append(csvData).append("\n");
//
//        // 插入到数据库
//        Score score = new Score();
//        score.setName(name);
//        score.setGoal(goal);
//        score.setScoreData(csvData);
//        score.setScoreType(scoreType);
//        score.setStatus("wait");
//        score.setUserId(loginUser.getId());
//        boolean saveResult = scoreService.save(score);
//        ThrowUtils.throwIf(!saveResult, ErrorCode.SYSTEM_ERROR, "图表保存失败");
//        long newScoreId = score.getId();
//        //TODO biMessageProducer.sendMessage(String.valueOf(newScoreId));
//        BiResponse biResponse = new BiResponse();
//        biResponse.setScoreId(newScoreId);
//        return ResultUtils.success(biResponse);
//    }
//
//
//    private void handleScoreUpdateError(long scoreId, String execMessage) {
//        Score updateScoreResult = new Score();
//        updateScoreResult.setId(scoreId);
//        updateScoreResult.setStatus("failed");
//        updateScoreResult.setExecMessage("execMessage");
//        boolean updateResult = scoreService.updateById(updateScoreResult);
//        if (!updateResult) {
//            log.error("更新图表失败状态失败" + scoreId + "," + execMessage);
//        }
//    }
//
//
//    /**
//     * 获取查询包装类
//     *
//     * @param scoreQueryRequest
//     * @return
//     */
//    private QueryWrapper<Score> getQueryWrapper(ScoreQueryRequest scoreQueryRequest) {
//        QueryWrapper<Score> queryWrapper = new QueryWrapper<>();
//        if (scoreQueryRequest == null) {
//            return queryWrapper;
//        }
//        Long id = scoreQueryRequest.getId();
//        String name = scoreQueryRequest.getName();
//        String goal = scoreQueryRequest.getGoal();
//        String scoreType = scoreQueryRequest.getScoreType();
//        Long userId = scoreQueryRequest.getUserId();
//        String sortField = scoreQueryRequest.getSortField();
//        String sortOrder = scoreQueryRequest.getSortOrder();
//
//        queryWrapper.eq(id != null && id > 0, "id", id);
//        queryWrapper.like(StringUtils.isNotBlank(name), "name", name);
//        queryWrapper.eq(StringUtils.isNotBlank(goal), "goal", goal);
//        queryWrapper.eq(StringUtils.isNotBlank(scoreType), "scoreType", scoreType);
//        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
//        queryWrapper.eq("isDelete", false);
//        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
//                sortField);
//        return queryWrapper;
//    }
//
//
//}
